#pragma once
#include <iostream>
#include <functional>
#include "Socket.hpp"
#include "Protocol.hpp"
#include "InetAddr.hpp"

using process_t = std::function<std::shared_ptr<Response>(std::shared_ptr<Request>)>;

class IOservice
{
public:
    IOservice(process_t process)
        : _process(process)
    {
    }

    void IOExcute(SockPtr sock, InetAddr &addr)
    {
        std::string packagestreamqueue;
        while(true)
        {
            // 读取数据
            ssize_t n = sock->Recv(&packagestreamqueue);
            if(n <= 0)
            {   
                printf("client %s quit or recv error\n", addr.Addrstr().c_str());
                break;
            }
            std::cout << "--------------------------------------------" << std::endl;
            std::cout << "packagestreamqueue: \n" << packagestreamqueue << std::endl;

            // 报文解析
            std::string package = Decode(packagestreamqueue);
            if(package.empty()) continue;

            auto req = Factory::BuildRequestDefault();
            std::cout << "Package is " << package << std::endl;

            // 反序列化
            req->Deserialize(package);

            // 业务处理
            auto resp = _process(req);

            // 序列化
            std::string respjson;
            resp->Serialize(&respjson);
            std::cout << "respjson: \n" << respjson << std::endl;      
            
            // 添加报头
            respjson = Encode(respjson);
            std::cout << "respjson add header done: \n" << respjson << std::endl;

            // 发送
            sock->Send(respjson); 
        }

    }

    ~IOservice()
    {
    }

private:
    process_t _process;
};